﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using Framework;

namespace Demo.ViewModels
{
    [Export("PersonViewModel", typeof (object))]
    public class PersonViewModel : BusinessObjectBase, IPartImportsSatisfiedNotification
    {
        private DelegateCommand _addPersonCommand;
        private DelegateCommand _deletePersonCommand;
        private DelegateCommand _editPersonCommand;


        private ObservableCollection<Person> _people;
        private Person _selectedPerson;

        [Import(ModalViewNames.EditPersonControlName)]
        public IModalView EditPersonControl { get; set; }

        [Import(ModalViewNames.DeleteControlName)]
        public IModalView DeleteControl { get; set; }

        [Import]
        public IModalDialog ModalDialog { get; set; }

        [Import]
        public IModalDialogWorker ModalDialogWorker { get; set; }

        [Import]
        public IPersonModel PersonModel { get; set; }

        public ObservableCollection<Person> People
        {
            get { return _people; }
            set
            {
                if (People == value)
                    return;

                _people = value;
                OnPropertyChanged("People");
            }
        }

        public Person SelectedPerson
        {
            get { return _selectedPerson; }
            set
            {
                if (SelectedPerson == value)
                    return;

                _selectedPerson = value;
                EditPersonCommand.RaiseCanExecuteChanged();
                DeletePersonCommand.RaiseCanExecuteChanged();
                OnPropertyChanged("SelectedPerson");
            }
        }

        public DelegateCommand AddPersonCommand
        {
            get { return _addPersonCommand ?? (_addPersonCommand = new DelegateCommand(OnAddPersonCommandExecute)); }
        }

        public DelegateCommand EditPersonCommand
        {
            get
            {
                return _editPersonCommand ??
                       (_editPersonCommand = new DelegateCommand(OnEditPersonCommandExecute,
                                                                OnEditPersonCommandCanExecute));
            }
        }

        public DelegateCommand DeletePersonCommand
        {
            get
            {
                return _deletePersonCommand ?? (_deletePersonCommand = new DelegateCommand(
                                                                         OnDeletePersonCommandExecute,
                                                                         OnDeletePersonCommandCanExecute));
            }
        }

        #region IPartImportsSatisfiedNotification Members

        public void OnImportsSatisfied()
        {
            People = PersonModel.LoadData();
        }

        #endregion

        private void OnAddPersonCommandExecute()
        {
            var newPerson = new Person {HireDate = DateTime.Now};

            ModalDialogWorker.ShowDialog(
                ModalDialog, EditPersonControl, newPerson, p =>
                                                               {
                                                                   if (ModalDialog.DialogResult.HasValue &&
                                                                       ModalDialog.DialogResult.Value)
                                                                   {
                                                                       People.Add(p);
                                                                   }
                                                               });
        }

        private void OnEditPersonCommandExecute()
        {
            var editableObject = new Caretaker<Person>(SelectedPerson);
            editableObject.BeginEdit();

            ModalDialogWorker.ShowDialog(
                ModalDialog, EditPersonControl, SelectedPerson, p =>
                                                                    {
                                                                        if (ModalDialog.DialogResult.HasValue &&
                                                                            ModalDialog.DialogResult.Value)
                                                                        {
                                                                            editableObject.EndEdit();
                                                                        }
                                                                        else
                                                                        {
                                                                            editableObject.CancelEdit();
                                                                        }
                                                                    });
        }

        private bool OnEditPersonCommandCanExecute()
        {
            return SelectedPerson != null;
        }

        private void OnDeletePersonCommandExecute()
        {
            ModalDialogWorker.ShowDialog(
                ModalDialog, DeleteControl, SelectedPerson, p =>
                                                                {
                                                                    if (ModalDialog.DialogResult.HasValue &&
                                                                        ModalDialog.DialogResult.Value)
                                                                    {
                                                                        People.Remove(p);
                                                                    }
                                                                });
        }

        private bool OnDeletePersonCommandCanExecute()
        {
            return SelectedPerson != null;
        }
    }
}